package com.tuo51.manager.controller;


import com.tuo51.evaluate.domain.appusers.RedeemCode;
import com.tuo51.evaluate.domain.appusers.StaffRedeemCode;
import com.tuo51.core.repositories.StaffRepository;
import com.tuo51.evaluate.repositories.appusers.RedeemCodeRepository;
import com.tuo51.evaluate.repositories.appusers.StaffRedeemCodeRepository;
import com.tuo51.core.service.StaffService;
import com.tuo51.evaluate.vo.RedeemCodeVO;
import com.tuo51.evaluate.vo.StaffRedeemRecord;
import com.tuo51.foudation.exception.BusinessException;
import com.tuo51.foudation.model.ErrorCode;
import com.tuo51.foudation.model.MemVerificationCache;
import com.tuo51.foudation.model.StatusResponse;
import com.tuo51.foudation.utils.CopyUtils;
import com.tuo51.manager.service.DataAnalysisService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import java.util.List;

import static com.tuo51.foudation.constant.RequestConstant.TICKET;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

@RestController
@RequestMapping("/mapi/redeemcode")
@Api(value = "/mapi/redeemcode", tags = "OP - 兑换码")
public class MAPIRedeemCodeController {

    @Autowired
    DataAnalysisService analysisService;

    @Autowired
    StaffService staffService;

    @Autowired
    StaffRepository staffRepository;

    @Autowired
    MemVerificationCache cache;

    @Autowired
    RedeemCodeRepository codeRepository;

    @Autowired
    StaffRedeemCodeRepository recordRepository;

    @RequestMapping(value = "/redeem_history", method = GET)
    @ApiOperation(value = "兑换记录")
    public StatusResponse history(@RequestHeader(TICKET) String ticket,
                                  @RequestParam(value = "pageNum", required = false, defaultValue = "0")Integer pageNum,
                                  @RequestParam(value = "pageSize", required = false, defaultValue = "15")Integer pageSize,
                                  @RequestParam(value = "redeemCodeId", required = false) String redeemCodeId,
                                  @RequestParam(value = "productId", required = false) String productId,
                                  @RequestParam(value = "staffId", required = false) String staffId,
                                  @RequestParam(value = "searchBy", required = false) String searchBy){

        cache.getStaffId(ticket);

        PageRequest pageRequest = PageRequest.of(pageNum, pageSize, Sort.by("created"));

        Page<StaffRedeemCode> page = null;

        if (StringUtils.isNotEmpty(redeemCodeId)) {
            page = recordRepository.findAllByRedeemCodeIdOrderByCreatedDesc(redeemCodeId, pageRequest);
        }else if(StringUtils.isNotEmpty(productId)){
            page = recordRepository.findAllByProductIdOrderByCreatedDesc(productId, pageRequest);
        }else if(StringUtils.isNotEmpty(staffId)) {
            page = recordRepository.findAllByStaffIdOrderByCreatedDesc(staffId, pageRequest);
        }else if(StringUtils.isNotEmpty(searchBy) && searchBy.length() >= 2){
            List<StaffRedeemCode> list = recordRepository.findAllByRedeemCodeLikeOrderByCreatedDesc(searchBy, pageRequest);
            long count = recordRepository.countAllByRedeemCodeLikeOrderByCreatedDesc(searchBy);
            page = new PageImpl<>(list, pageRequest, count);
        }else{
            page = recordRepository.findAllByOrderByCreatedDesc(pageRequest);
        }

        Page<StaffRedeemRecord> ret = page.map(
                k-> {
                    StaffRedeemRecord r = StaffRedeemRecord.of(k);
                    r.setOrg(staffService.staffOrgnization(r.getStaff()));
                    return r;
                }
        );

        return StatusResponse.success(ret);
    }

    @RequestMapping(value = "/list", method = GET)
    @ApiOperation(value = "资源列表")
    public StatusResponse list(@RequestHeader(TICKET) String ticket,
                               @RequestParam(value = "pageNum", required = false, defaultValue = "0")Integer pageNum,
                               @RequestParam(value = "pageSize", required = false, defaultValue = "15")Integer pageSize,
                               @RequestParam(value = "productId", required = false) Long productId,
                               @RequestParam(value = "searchBy", required = false) String searchBy){

        cache.getStaffId(ticket);

        PageRequest pageRequest = PageRequest.of(pageNum, pageSize);

        Page<RedeemCode> ret = codeRepository.findAll(new Specification<RedeemCode>() {
            @Override
            public Predicate toPredicate(Root<RedeemCode> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

                Predicate base = cb.isNotNull(root.get("id"));

                if (StringUtils.isNotEmpty(searchBy)){
                    String key = "%" + searchBy + "%";
                    Predicate p = cb.or(cb.like(root.get("code"), key),
                            cb.like(root.get("dealer"), key));
                    base = cb.and(base, p);
                }

                if (productId != null){
                    Predicate p = cb.equal(root.get("product_id"), productId);
                    base = cb.and(base, p);
                }

                base = cb.and(base, cb.isFalse(root.get("deleted")));

                query.where(base);

                query.orderBy(cb.desc(root.get("salesQuantity")), cb.desc(root.get("created")));

                return query.getRestriction();
            }
        }, pageRequest);

        return StatusResponse.success(ret);
    }

    @RequestMapping(value = "/info", method = GET)
    @ApiOperation(value = "内容详情")
    public StatusResponse info(@RequestHeader(TICKET) String ticket, String codeId){
        cache.getStaffId(ticket);

        RedeemCode ret = codeRepository.getOne(codeId);

        if (ret == null){
            throw new BusinessException(ErrorCode.MATERIAL_NOT_EXIST, "条目不存在");
        }

        return StatusResponse.success(ret);
    }

    @RequestMapping(value = "/edit", method = POST)
    @ApiOperation(value = "兑换码编辑 或 创建")
    public StatusResponse edit(@RequestHeader(TICKET) String ticket,
                               RedeemCodeVO redeemCode){
        cache.getStaffId(ticket);

        cache.getStaffId(ticket);

        RedeemCode ret = null;
        if (redeemCode.getId() != null){
            ret = codeRepository.getOne(redeemCode.getId());
        }else{
            ret = new RedeemCode();
        }
        CopyUtils.copyProperties(redeemCode, ret);

        codeRepository.save(ret);

        return StatusResponse.success(ret);
    }


    @RequestMapping(value = "/delete", method = POST)
    @ApiOperation(value = "删除")
    public StatusResponse delete(@RequestHeader(TICKET) String ticket,
                                 String id){
        cache.getStaffId(ticket);

        if (StringUtils.isEmpty(id)){
            throw new BusinessException(ErrorCode.PARAM_NOT_BLANK, "参数错误");
        }

        RedeemCode item = codeRepository.getOne(id);
        if (item == null){
            throw new BusinessException(ErrorCode.MATERIAL_NOT_EXIST, "对象不存在");
        }

        item.setDeleted(true);
        codeRepository.save(item);

        return StatusResponse.success(true);
    }
}
